﻿Imports System.Net.WebSockets
Imports System.Text
Imports System.Threading
Imports Microsoft.AspNetCore.Http

Namespace gWebSocket
    Public Class wss
        Public Shared clList As New List(Of clist)() '当前在线的用户
    End Class
    Public Class clist
        Dim ss As Net.WebSockets.WebSocket, uuid As String, id As String
        Public Sub New(ByVal soc As Net.WebSockets.WebSocket, ByVal suuid As String, ByVal uid As String)
            ss = soc
            uuid = suuid
            id = uid
        End Sub
        Public ReadOnly Property clid As String
            Get
                Return id
            End Get
        End Property
        Public ReadOnly Property cluuid As String
            Get
                Return uuid
            End Get
        End Property
        Public ReadOnly Property clss As Net.WebSockets.WebSocket
            Get
                Return ss
            End Get
        End Property
    End Class
    Public Class wsapi
        Public Shared Sub RemoveclList(ByVal suuid As String)
            For i = 0 To wss.clList.Count - 1
                If wss.clList(i).cluuid = suuid Then
                    wss.clList(i).clss.Abort()
                    wss.clList.Remove(wss.clList(i))
                    Exit For
                End If
            Next
        End Sub
        Public Shared Async Function SocketHandler(ByVal context As HttpContext, ByVal ws As WebSocket) As Task
            Dim uuid As String = Guid.NewGuid.ToString.Replace("-", "")
            Dim id As String = uuid
            Dim slist As New clist(ws, uuid, id)
            wss.clList.Add(slist)
            Dim Buffer As New ArraySegment(Of Byte)(New Byte(10240) {}), Result As WebSocketReceiveResult, cout As Integer = 0, ms As IO.MemoryStream = Nothing
            While True '一直扫描状态
                Try
                    If ms Is Nothing Then
                        ms = New IO.MemoryStream
                    End If
                    Select Case ws.State'连接状态
                        Case WebSocketState.None, WebSocketState.Connecting '正在连接不处理
                        Case WebSocketState.Open '已连接
                            Result = Await ws.ReceiveAsync(Buffer, CancellationToken.None)
                            cout += Result.Count
                            Await ms.WriteAsync(ms.ToArray, 0, cout)
                            If Result.EndOfMessage = True AndAlso cout > 0 Then
                                Dim rstr As String = Encoding.UTF8.GetString(ms.ToArray, 0, cout), ids As String = id, isall As Boolean = False
                                cout = 0
                                ms.Dispose()
                                ms = Nothing
                                '转发收到的消息
                                Message(id, rstr, uuid)
                            End If
                        Case WebSocketState.CloseSent, WebSocketState.CloseReceived, WebSocketState.Closed, WebSocketState.Aborted '断开连接
                            RemoveclList(uuid)  '下线
                            Exit While
                    End Select
                    Thread.Sleep(1) '延迟1豪秒
                Catch ex As Exception
                    'IO.File.AppendAllText("D:\1.txt", ex.Message & vbCrLf)
                End Try
            End While
        End Function
        '处理接受到的消息内容
        Shared Sub Message(ByVal id As String, ByVal sstr As String, ByVal suuid As String)
            Try
                For i = 0 To wss.clList.Count - 1
                    If wss.clList(i).clid = id Then
                        sendMessage(i, sstr)
                        Exit For
                    End If
                Next
            Catch ex As Exception
                RemoveclList(suuid)
                'IO.File.AppendAllText("D:\2.txt", ex.Message & vbCrLf)
            End Try
        End Sub
        Shared Async Sub sendMessage(ByVal idx As Integer, ByVal sstr As String)
            Try
                Await wss.clList(idx).clss.SendAsync(New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes(sstr)), WebSocketMessageType.Text, True, CancellationToken.None)
            Catch ex As Exception
                wss.clList(idx).clss.Abort()
                wss.clList.Remove(wss.clList(idx))
                'IO.File.AppendAllText("D:\3.txt", ex.Message & vbCrLf)
            End Try
        End Sub
    End Class
End Namespace